package com.aisino.springai.demos.chat.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.mcp.client.McpClient;
import org.springframework.ai.mcp.client.McpSyncClient;
import org.springframework.ai.mcp.client.transport.ServerParameters;
import org.springframework.ai.mcp.client.transport.StdioClientTransport;
import org.springframework.ai.mcp.spring.McpFunctionCallback;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.nio.file.Paths;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;

/**
 * @author guochuantao
 * @version 1.0
 * @description
 * @since 2025/4/7 下午5:15
 */
// 服务配置（McpConfig.java）
@Configuration
public class McpConfig {
    /**
     * 创建MCP客户端
     */
    @Bean(destroyMethod = "close")
    public McpSyncClient mcpClient(ObjectMapper objectMapper) {
        // 1. 配置标准输入输出传输（StdioServerTransport）
/*        var serverParameters = ServerParameters.builder("npx.cmd")
                .args("-y", "@modelcontextprotocol/server-filesystem",
                       getFilePath()).build();*/
        var serverParameters = ServerParameters.builder("node").args(
                "D:\\nvm\\nodejs\\node_modules\\@modelcontextprotocol\\server-filesystem\\dist"
                , getFilePath()
        ).build();
        // 创建同步MCP客户端
        var mcpClient = McpClient.using(new StdioClientTransport(serverParameters))
                .requestTimeout(Duration.ofSeconds(10)).sync();

        var init = mcpClient.initialize();
        System.err.println("初始化结果：" + init);

        return mcpClient;
    }

    /**
     * 获取文件路径 如果找不到文件需要将 配置更改为当前工作目录
     */
    private static String getFilePath() {
        String path = System.getenv("MCP_FILE_DIRECTORY_PATH");
        String finalPath = StringUtils.isEmpty(path) ? getDbPath() : path;
        System.err.println("文件路径：" + finalPath);
        return finalPath;
    }

    private static String getDbPath() {
        return Paths.get(System.getProperty("user.dir")).toString();
    }

    /**
     * 创建MCP回调函数 将mcp服务器中的工具列表转化为Function Callbac List<McpFunctionCallback>
     */
    @Bean
    public List<McpFunctionCallback> functionCallbacks(McpSyncClient mcpClient) {
        // 获取MCP服务器中的工具列表
        return mcpClient.listTools(null)
                // 将每个工具转换为Function Callback
                .tools()
                .stream()
                .map(tool -> new McpFunctionCallback(mcpClient, tool))
                .toList();
    }

    /**
     * 创建MCP聊天客户端
     */
    @Bean
    public ChatClient mcpChatClient(ChatClient.Builder chatClient, List<McpFunctionCallback> functionCallbacks) {
        System.err.println(Arrays.toString(functionCallbacks.toArray(FunctionCallback[]::new)));
        return chatClient.defaultFunctions(functionCallbacks.toArray(new McpFunctionCallback[0]))
                .defaultSystem("MCP Server 文件系统")
                .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
                .build();
    }
}
